<?php
namespace app\swoole\Console;

use app\swoole\ThinksCore;
use think\App;
use think\Config;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
use think\exception\HttpResponseException;
use think\Hook;
use think\Lang;
use think\Loader;
use think\Log;
use think\Request;
use think\Response;
use think\Route;

class Command extends \think\console\Command
{
    private $basePath;
    private $thinksCore;

    private static $config;
    private static $request;
    protected static $dispatch;

    private $_input;
    private $_output;

    public function __construct($bathPath = null)
    {
        $this->basePath = $bathPath;
        parent::__construct('thinkphps');
    }

    public function execute(Input $input, Output $output)
    {
        $this->_input = $input;
        $this->_output = $output;
        try {
            $action = $input->getArgument('action');

            $this->thinksCore = new \app\swoole\src\ThinksCore();
            switch ($action) {
                case 'start':
                    $this->start();
                    break;
                case 'stop':
                    $this->stop();
                    break;
                case 'restart':
                    $this->restart();
                    break;
                case 'reload':
                    $this->reload();
                    break;
                case 'info':
                default:
                $this->_output->comment('Speed up your THINKPHP');
                    $help = <<<EOS
                    
Usage:
  [%s] ./bin/tp_swools [options]

Action:
  action                start|stop|restart|reload|info|help

EOS;
                    $this->output->writeln(sprintf($help, PHP_BINARY));
                    break;
            }
        } catch (\Exception $e) {
            $error = sprintf(
                'Uncaught exception "%s"([%d]%s) at %s:%s, %s%s',
                get_class($e),
                $e->getCode(),
                $e->getMessage(),
                $e->getFile(),
                $e->getLine(),
                PHP_EOL,
                $e->getTraceAsString()
            );
        }
    }

    public function configure()
    {
        $this->setName('thinkphps')->addArgument('action');
    }

    public function start()
    {
        $this->thinksCore->start();
    }

    public function handleFatal()
    {
        $error = error_get_last();
        if (isset($error['type']))
        {
            switch ($error['type'])
            {
                case E_ERROR :
                case E_PARSE :
                case E_CORE_ERROR :
                case E_COMPILE_ERROR :
                    $message = $error['message'];
                    $file = $error['file'];
                    $line = $error['line'];
                    $log = "$message ($file:$line)\nStack trace:\n";
                    $trace = debug_backtrace();
                    foreach ($trace as $i => $t)
                    {
                        if (!isset($t['file']))
                        {
                            $t['file'] = 'unknown';
                        }
                        if (!isset($t['line']))
                        {
                            $t['line'] = 0;
                        }
                        if (!isset($t['function']))
                        {
                            $t['function'] = 'unknown';
                        }
                        $log .= "#$i {$t['file']}({$t['line']}): ";
                        if (isset($t['object']) and is_object($t['object']))
                        {
                            $log .= get_class($t['object']) . '->';
                        }
                        $log .= "{$t['function']}()\n";
                    }
                    if (isset($_SERVER['REQUEST_URI']))
                    {
                        $log .= '[QUERY] ' . $_SERVER['REQUEST_URI'];
                    }
                    error_log($log);
                    $serv->send($this->currentFd, $log);
                default:
                    break;
            }
        }
    }
}